/*     */ package com.zimbra.cs.zimlet;
/*     */ 
/*     */ import com.zimbra.common.util.ByteUtil;
/*     */ import com.zimbra.common.util.TemplateCompiler;
/*     */ import java.io.ByteArrayInputStream;
/*     */ import java.io.File;
/*     */ import java.io.FileInputStream;
/*     */ import java.io.FileNotFoundException;
/*     */ import java.io.IOException;
/*     */ import java.io.InputStream;
/*     */ import java.net.MalformedURLException;
/*     */ import java.net.URL;
/*     */ import java.util.Collection;
/*     */ import java.util.Enumeration;
/*     */ import java.util.HashMap;
/*     */ import java.util.Map;
/*     */ import java.util.jar.Attributes;
/*     */ import java.util.jar.JarFile;
/*     */ import java.util.jar.JarInputStream;
/*     */ import java.util.jar.Manifest;
/*     */ import java.util.regex.Matcher;
/*     */ import java.util.regex.Pattern;
/*     */ import java.util.zip.ZipEntry;
/*     */ import java.util.zip.ZipFile;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class ZimletFile
/*     */   implements Comparable<ZimletFile>
/*     */ {
/*     */   private File mBase;
/*     */   private InputStream mBaseStream;
/*     */   private byte[] mCopy;
/*  54 */   private static Pattern BAD_FILE_NAME_PATTERN = Pattern.compile("(\\.\\.\\/)|(\\p{Cntrl})");
/*     */   
/*  56 */   public int compareTo(ZimletFile obj) { return getZimletName().compareTo(obj.getZimletName()); }
/*     */   
/*     */   public static abstract class ZimletEntry
/*     */   {
/*     */     protected String mName;
/*     */     
/*     */     protected ZimletEntry(String name) throws ZimletException
/*     */     {
/*  64 */       Matcher nameMatcher = ZimletFile.BAD_FILE_NAME_PATTERN.matcher(name);
/*  65 */       if (nameMatcher.find()) {
/*  66 */         throw ZimletException.INVALID_ZIMLET_ENTRY(name);
/*     */       }
/*  68 */       if (new File(name).isAbsolute()) {
/*  69 */         throw ZimletException.INVALID_ABSOLUTE_PATH(name);
/*     */       }
/*  71 */       this.mName = name;
/*     */     }
/*     */     
/*     */     public String getName() {
/*  75 */       return this.mName;
/*     */     }
/*     */     
/*     */     public abstract byte[] getContents() throws IOException;
/*     */     
/*     */     public abstract InputStream getContentStream() throws IOException;
/*     */   }
/*     */   
/*     */   public static class ZimletZipEntry extends ZimletFile.ZimletEntry {
/*     */     private ZipFile mContainer;
/*     */     private ZipEntry mEntry;
/*     */     
/*     */     public ZimletZipEntry(ZipFile f, ZipEntry e) throws ZimletException {
/*  88 */       super();
/*  89 */       this.mContainer = f;
/*  90 */       this.mEntry = e;
/*     */     }
/*     */     
/*     */     public byte[] getContents() throws IOException {
/*  94 */       InputStream is = this.mContainer.getInputStream(this.mEntry);
/*  95 */       byte[] ret = ByteUtil.getContent(is, (int)this.mEntry.getSize());
/*  96 */       is.close();
/*  97 */       return ret;
/*     */     }
/*     */     
/*     */     public InputStream getContentStream() throws IOException {
/* 101 */       return this.mContainer.getInputStream(this.mEntry);
/*     */     }
/*     */   }
/*     */   
/*     */   public static class ZimletDirEntry extends ZimletFile.ZimletEntry {
/*     */     private File mFile;
/*     */     
/*     */     public ZimletDirEntry(File f) throws ZimletException {
/* 109 */       super();
/* 110 */       this.mFile = f;
/*     */     }
/*     */     
/*     */     public byte[] getContents() throws IOException {
/* 114 */       InputStream is = new FileInputStream(this.mFile);
/* 115 */       byte[] ret = ByteUtil.getContent(is, (int)this.mFile.length());
/* 116 */       is.close();
/* 117 */       return ret;
/*     */     }
/*     */     
/*     */     public InputStream getContentStream() throws IOException {
/* 121 */       return new FileInputStream(this.mFile);
/*     */     }
/*     */   }
/*     */   
/*     */   public static class ZimletRawEntry extends ZimletFile.ZimletEntry {
/*     */     private byte[] mData;
/*     */     
/*     */     public ZimletRawEntry(InputStream is, String name, int size) throws IOException, ZimletException {
/* 129 */       super();
/* 130 */       this.mData = new byte[size];
/*     */       
/*     */ 
/* 133 */       int offset = 0;
/* 134 */       int len = size;
/* 135 */       int num; while ((len > 0) && ((num = is.read(this.mData, offset, len)) != -1)) {
/* 136 */         offset += num;
/* 137 */         len -= num;
/*     */       }
/*     */     }
/*     */     
/*     */     public byte[] getContents() throws IOException {
/* 142 */       return this.mData;
/*     */     }
/*     */     
/*     */     public InputStream getContentStream() throws IOException {
/* 146 */       return new ByteArrayInputStream(this.mData);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */   private static final String XML_SUFFIX = ".xml";
/*     */   
/*     */   private static final String ZIP_SUFFIX = ".zip";
/*     */   private static final String CONFIG_TMPL = "config_template.xml";
/*     */   private String mDescFile;
/*     */   private Map<String, ZimletEntry> mEntries;
/*     */   private ZimletDescription mDesc;
/*     */   private String mDescString;
/*     */   private ZimletConfig mConfig;
/*     */   private String mConfigString;
/*     */   private String mZimletName;
/*     */   public ZimletFile(String zimlet)
/*     */     throws IOException, ZimletException
/*     */   {
/* 165 */     this.mBase = new File(findZimlet(zimlet));
/* 166 */     initialize();
/*     */   }
/*     */   
/*     */   public ZimletFile(File parent, String zimlet) throws IOException, ZimletException {
/* 170 */     this.mBase = new File(parent, zimlet);
/* 171 */     initialize();
/*     */   }
/*     */   
/*     */   public ZimletFile(String name, InputStream is) throws IOException, ZimletException {
/* 175 */     this.mBaseStream = is;
/* 176 */     initialize(name);
/*     */   }
/*     */   
/*     */   private void initialize() throws IOException, ZimletException {
/* 180 */     String name = this.mBase.getName().toLowerCase();
/* 181 */     int index = name.lastIndexOf(File.separatorChar);
/* 182 */     if (index > 0) {
/* 183 */       name = name.substring(index + 1);
/*     */     }
/* 185 */     initialize(name);
/*     */   }
/*     */   
/*     */   private void initialize(String name) throws IOException, ZimletException
/*     */   {
/* 190 */     if (!name.matches("^[\\w.-]+$"))
/*     */     {
/*     */ 
/* 193 */       throw ZimletException.INVALID_ZIMLET_NAME();
/*     */     }
/* 195 */     if (name.endsWith(".zip")) {
/* 196 */       name = name.substring(0, name.length() - 4);
/*     */     }
/* 198 */     this.mDescFile = (name + ".xml");
/*     */     
/* 200 */     this.mEntries = new HashMap();
/*     */     
/* 202 */     if (this.mBaseStream != null) {
/* 203 */       this.mCopy = ByteUtil.getContent(this.mBaseStream, 0);
/* 204 */       JarInputStream zis = new JarInputStream(new ByteArrayInputStream(this.mCopy));
/* 205 */       Manifest mf = zis.getManifest();
/* 206 */       if (mf != null) {
/* 207 */         this.mDescFile = mf.getMainAttributes().getValue("Zimlet-Description-File");
/*     */       }
/* 209 */       ZipEntry entry = zis.getNextEntry();
/* 210 */       while (entry != null) {
/* 211 */         if (entry.getSize() > 0L) {
/* 212 */           this.mEntries.put(entry.getName().toLowerCase(), new ZimletRawEntry(zis, entry.getName(), (int)entry.getSize()));
/*     */         }
/* 214 */         zis.closeEntry();
/* 215 */         entry = zis.getNextEntry();
/*     */       }
/* 217 */       zis.close();
/* 218 */     } else if (this.mBase.isDirectory()) {
/* 219 */       addFileEntry(this.mBase, "");
/*     */     } else {
/* 221 */       JarFile jar = new JarFile(this.mBase);
/* 222 */       Manifest mf = jar.getManifest();
/* 223 */       if (mf != null) {
/* 224 */         this.mDescFile = mf.getMainAttributes().getValue("Zimlet-Description-File");
/*     */       }
/* 226 */       Enumeration entries = jar.entries();
/* 227 */       while (entries.hasMoreElements()) {
/* 228 */         ZipEntry entry = (ZipEntry)entries.nextElement();
/* 229 */         if (entry.getSize() > 0L) {
/* 230 */           this.mEntries.put(entry.getName().toLowerCase(), new ZimletZipEntry(jar, entry));
/*     */         }
/*     */       }
/*     */     }
/* 234 */     initZimletDescription();
/* 235 */     this.mZimletName = this.mDesc.getName();
/*     */   }
/*     */   
/*     */   private void addFileEntry(File f, String dir) throws IOException, ZimletException {
/* 239 */     addFileEntry(f, dir, f);
/*     */   }
/*     */   
/*     */   private void addFileEntry(File f, String dir, File base) throws IOException, ZimletException {
/* 243 */     File[] files = f.listFiles();
/* 244 */     if (files == null)
/* 245 */       return;
/* 246 */     for (File file : files) {
/* 247 */       String name = (dir.length() == 0 ? "" : new StringBuilder().append(dir).append("/").toString()) + file.getName().toLowerCase();
/* 248 */       if (file.isDirectory()) {
/* 249 */         addFileEntry(file, name, base);
/*     */       }
/*     */       else {
/* 252 */         if (!name.endsWith(".template.js")) {
/* 253 */           this.mEntries.put(name, new ZimletDirEntry(file));
/*     */         }
/* 255 */         if (name.endsWith(".template"))
/* 256 */           addTemplateFileEntry(file, dir, base);
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */   private void addTemplateFileEntry(File ifile, String dir, File base) throws IOException, ZimletException {
/* 262 */     File ofile = new File(ifile.getParentFile(), ifile.getName() + ".js");
/* 263 */     if ((!ofile.exists()) || (ifile.lastModified() > ofile.lastModified())) {
/* 264 */       String prefix = base.getName() + ".";
/* 265 */       String dirname = base.getAbsolutePath();
/* 266 */       if (!dirname.endsWith(File.separator))
/* 267 */         dirname = dirname + File.separatorChar;
/* 268 */       String filename = ifile.getAbsolutePath().substring(dirname.length());
/* 269 */       String pkg = prefix + filename.replaceAll("\\.[^\\.]+$", "").replace(File.separatorChar, '.');
/* 270 */       TemplateCompiler.compile(ifile, ofile, pkg, true, true);
/*     */     }
/* 272 */     String name = (dir.length() == 0 ? "" : new StringBuilder().append(dir).append("/").toString()) + ofile.getName().toLowerCase();
/* 273 */     this.mEntries.put(name, new ZimletDirEntry(ofile));
/*     */   }
/*     */   
/*     */   private void initZimletDescription() throws IOException, ZimletException {
/* 277 */     if (this.mDesc == null) {
/* 278 */       ZimletEntry entry = (ZimletEntry)this.mEntries.get(this.mDescFile.toLowerCase());
/* 279 */       if (entry == null) {
/* 280 */         throw new FileNotFoundException("zimlet description not found: " + this.mDescFile);
/*     */       }
/* 282 */       this.mDescString = new String(entry.getContents(), "UTF-8");
/* 283 */       this.mDesc = new ZimletDescription(this.mDescString);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public String getZimletDescString()
/*     */     throws IOException, ZimletException
/*     */   {
/* 294 */     initZimletDescription();
/* 295 */     return this.mDescString;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public ZimletDescription getZimletDescription()
/*     */     throws IOException, ZimletException
/*     */   {
/* 305 */     initZimletDescription();
/* 306 */     return this.mDesc;
/*     */   }
/*     */   
/*     */   public boolean hasZimletConfig() {
/* 310 */     return this.mEntries.containsKey("config_template.xml");
/*     */   }
/*     */   
/*     */   private void initZimletConfig() throws IOException, ZimletException {
/* 314 */     if (this.mConfig == null) {
/* 315 */       ZimletEntry entry = (ZimletEntry)this.mEntries.get("config_template.xml");
/* 316 */       if (entry == null) {
/* 317 */         throw new FileNotFoundException("zimlet config not found: config_template.xml");
/*     */       }
/* 319 */       this.mConfigString = new String(entry.getContents());
/* 320 */       this.mConfig = new ZimletConfig(this.mConfigString);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public String getZimletConfigString()
/*     */     throws IOException, ZimletException
/*     */   {
/* 331 */     initZimletConfig();
/* 332 */     return this.mConfigString;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public ZimletConfig getZimletConfig()
/*     */     throws IOException, ZimletException
/*     */   {
/* 342 */     initZimletConfig();
/* 343 */     return this.mConfig;
/*     */   }
/*     */   
/*     */   public ZimletEntry getEntry(String name) {
/* 347 */     return (ZimletEntry)this.mEntries.get(name.toLowerCase());
/*     */   }
/*     */   
/*     */   public Collection<ZimletEntry> getAllEntries() {
/* 351 */     return this.mEntries.values();
/*     */   }
/*     */   
/*     */   public String getZimletName() {
/* 355 */     return this.mZimletName;
/*     */   }
/*     */   
/*     */   public String getName() {
/* 359 */     return getZimletName() + ".zip";
/*     */   }
/*     */   
/*     */   public URL toURL() throws MalformedURLException {
/* 363 */     return this.mBase.toURL();
/*     */   }
/*     */   
/*     */   public File getFile() {
/* 367 */     return this.mBase;
/*     */   }
/*     */   
/*     */   private static String findZimlet(String zimlet) throws FileNotFoundException {
/* 371 */     File zimletFile = new File(zimlet);
/*     */     
/* 373 */     if (!zimletFile.exists()) {
/* 374 */       zimletFile = new File(zimlet + ".zip");
/* 375 */       if (!zimletFile.exists()) {
/* 376 */         throw new FileNotFoundException("Zimlet not found: " + zimlet);
/*     */       }
/*     */     }
/*     */     
/* 380 */     if (zimletFile.isDirectory()) {
/* 381 */       String[] files = zimletFile.list();
/* 382 */       String zimletTargetName = zimletFile.getName() + ".zip";
/*     */       
/* 384 */       for (int i = 0; i < files.length; i++) {
/* 385 */         if (files[i].equals(zimletTargetName)) {
/* 386 */           return zimlet + File.separator + files[i];
/*     */         }
/*     */       }
/*     */     }
/*     */     
/* 391 */     return zimlet;
/*     */   }
/*     */   
/*     */   public byte[] toByteArray() {
/* 395 */     return this.mCopy;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/zimlet/ZimletFile.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */